pcifront poll loop now checks gettimeofday rather than jiffies,
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 16 Mar 2006 11:31:16 +0000 (12:31 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 16 Mar 2006 11:31:16 +0000 (12:31 +0100)
as the latter does not increase while interrupts are disabled.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c

index 501736ff5a57a3e1dbfa6611fe3c56344c8a94b5..1b2ff313c3f253e062e4dc30e2ef174606675854 100644 (file)
@@ -40,8 +40,10 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
 {
        int err = 0;
        struct xen_pci_op *active_op = &pdev->sh_info->op;
-       unsigned long irq_flags, poll_end;
+       unsigned long irq_flags;
        evtchn_port_t port = pdev->evtchn;
+       nsec_t ns, ns_timeout;
+       struct timeval tv;
 
        spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
 
@@ -52,15 +54,25 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
        set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
        notify_remote_via_evtchn(port);
 
-       poll_end = jiffies + 5*HZ;
+       /*
+        * We set a poll timeout of 5 seconds but give up on return after
+        * 4 seconds. It is better to time out too late rather than too early
+        * (in the latter case we end up continually re-executing poll() with a
+        * timeout in the past). 1s difference gives plenty of slack for error.
+        */
+       do_gettimeofday(&tv);
+       ns_timeout = timeval_to_ns(&tv) + 4 * (nsec_t)NSEC_PER_SEC;
+
        clear_evtchn(port);
 
        while (test_bit(_XEN_PCIF_active,
                        (unsigned long *)&pdev->sh_info->flags)) {
-               if (HYPERVISOR_poll(&port, 1, poll_end))
+               if (HYPERVISOR_poll(&port, 1, jiffies + 5*HZ))
                        BUG();
                clear_evtchn(port);
-               if (time_after(jiffies, poll_end)) {
+               do_gettimeofday(&tv);
+               ns = timeval_to_ns(&tv);
+               if (ns > ns_timeout) {
                        dev_err(&pdev->xdev->dev,
                                "pciback not responding!!!\n");
                        clear_bit(_XEN_PCIF_active,